From: Keir Fraser Date: Tue, 30 Oct 2007 16:11:47 +0000 (+0000) Subject: x86, hvm: New timer mode 'no missed-tick accounting'. X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~14828^2~2 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/%22/%22http:/www.example.com/cgi/%22?a=commitdiff_plain;h=edba492627726fbeaba2dee066156adcf02467d8;p=xen.git x86, hvm: New timer mode 'no missed-tick accounting'. From: Haitao Shan Signed-off-by: Keir Fraser --- diff --git a/xen/arch/x86/hvm/vpt.c b/xen/arch/x86/hvm/vpt.c index ec0ac0b11c..605a572283 100644 --- a/xen/arch/x86/hvm/vpt.c +++ b/xen/arch/x86/hvm/vpt.c @@ -23,11 +23,8 @@ #include #include -static int pt_support_time_frozen(struct domain *d) -{ - return (d->arch.hvm_domain.params[HVM_PARAM_TIMER_MODE] == - HVMPTM_delay_for_missed_ticks); -} +#define mode_is(d, name) \ + ((d)->arch.hvm_domain.params[HVM_PARAM_TIMER_MODE] == HVMPTM_##name) static void pt_lock(struct periodic_time *pt) { @@ -48,7 +45,7 @@ static void pt_unlock(struct periodic_time *pt) spin_unlock(&pt->vcpu->arch.hvm_vcpu.tm_lock); } -static void missed_ticks(struct periodic_time *pt) +static void pt_process_missed_ticks(struct periodic_time *pt) { s_time_t missed_ticks; @@ -73,11 +70,26 @@ static void missed_ticks(struct periodic_time *pt) pt->scheduled += missed_ticks * pt->period; } -static __inline__ void pt_freeze_time(struct vcpu *v) +static void pt_freeze_time(struct vcpu *v) { + if ( !mode_is(v->domain, delay_for_missed_ticks) ) + return; + v->arch.hvm_vcpu.guest_time = hvm_get_guest_time(v); } +static void pt_thaw_time(struct vcpu *v) +{ + if ( !mode_is(v->domain, delay_for_missed_ticks) ) + return; + + if ( v->arch.hvm_vcpu.guest_time == 0 ) + return; + + hvm_set_guest_time(v, v->arch.hvm_vcpu.guest_time); + v->arch.hvm_vcpu.guest_time = 0; +} + void pt_save_timer(struct vcpu *v) { struct list_head *head = &v->arch.hvm_vcpu.tm_list; @@ -91,21 +103,11 @@ void pt_save_timer(struct vcpu *v) list_for_each_entry ( pt, head, list ) stop_timer(&pt->timer); - if ( pt_support_time_frozen(v->domain) ) - pt_freeze_time(v); + pt_freeze_time(v); spin_unlock(&v->arch.hvm_vcpu.tm_lock); } -static __inline__ void pt_thaw_time(struct vcpu *v) -{ - if ( v->arch.hvm_vcpu.guest_time ) - { - hvm_set_guest_time(v, v->arch.hvm_vcpu.guest_time); - v->arch.hvm_vcpu.guest_time = 0; - } -} - void pt_restore_timer(struct vcpu *v) { struct list_head *head = &v->arch.hvm_vcpu.tm_list; @@ -115,12 +117,12 @@ void pt_restore_timer(struct vcpu *v) list_for_each_entry ( pt, head, list ) { - missed_ticks(pt); + if ( !mode_is(v->domain, no_missed_tick_accounting) ) + pt_process_missed_ticks(pt); set_timer(&pt->timer, pt->scheduled); } - if ( pt_support_time_frozen(v->domain) ) - pt_thaw_time(v); + pt_thaw_time(v); spin_unlock(&v->arch.hvm_vcpu.tm_lock); } @@ -136,7 +138,15 @@ static void pt_timer_fn(void *data) if ( !pt->one_shot ) { pt->scheduled += pt->period; - missed_ticks(pt); + if ( !mode_is(pt->vcpu->domain, no_missed_tick_accounting) ) + { + pt_process_missed_ticks(pt); + } + else if ( (NOW() - pt->scheduled) >= 0 ) + { + pt->pending_intr_nr++; + pt->scheduled = NOW() + pt->period; + } set_timer(&pt->timer, pt->scheduled); } @@ -233,11 +243,14 @@ void pt_intr_post(struct vcpu *v, struct hvm_intack intack) else { pt->pending_intr_nr--; - pt->last_plt_gtime += pt->period_cycles; + if ( mode_is(v->domain, no_missed_tick_accounting) ) + pt->last_plt_gtime = hvm_get_guest_time(v); + else + pt->last_plt_gtime += pt->period_cycles; } - if ( pt_support_time_frozen(v->domain) && - hvm_get_guest_time(v) < pt->last_plt_gtime ) + if ( mode_is(v->domain, delay_for_missed_ticks) && + (hvm_get_guest_time(v) < pt->last_plt_gtime) ) hvm_set_guest_time(v, pt->last_plt_gtime); cb = pt->cb; diff --git a/xen/include/public/hvm/params.h b/xen/include/public/hvm/params.h index dbf2fb0b44..9fa80d39e7 100644 --- a/xen/include/public/hvm/params.h +++ b/xen/include/public/hvm/params.h @@ -66,10 +66,14 @@ * no_delay_for_missed_ticks: * As above, missed interrupts are delivered, but guest time always tracks * wallclock (i.e., real) time while doing so. + * no_missed_ticks_pending: + * No more than one missed interrupt is held pending, and guest time always + * tracks wallclock (i.e., real) time. */ #define HVM_PARAM_TIMER_MODE 10 #define HVMPTM_delay_for_missed_ticks 0 #define HVMPTM_no_delay_for_missed_ticks 1 +#define HVMPTM_no_missed_tick_accounting 2 #define HVM_NR_PARAMS 11